<script setup lang="ts">
import { ref, watch } from 'vue'
import { useEventListener } from '@vueuse/core'
import { User, Lock } from '@element-plus/icons-vue'
import { useRoute, useRouter, type LocationQuery } from 'vue-router'
import type { FormInstance } from 'element-plus'
import { useUserStore } from '@/store/user'
import { captchaImage } from '@/api/global'
import Cookies from 'js-cookie'
import { encrypt, decrypt } from '@/utils/jsencrypt'
import to from 'await-to-js'
import { debounce } from 'es-toolkit'

const loading = ref(false)
const appTitle = import.meta.env.VITE_GLOB_APP_TITLE
const route = useRoute()
const router = useRouter()
const redirect = ref<string | null>(null)
const otherQuery = ref({})
function getOtherQuery(query: LocationQuery) {
	return Object.keys(query).reduce((pre, cur) => {
		if (cur !== 'redirect') (pre as Record<string, unknown>)[cur] = query[cur]
		return pre
	}, {})
}
watch(
	route,
	() => {
		const query = route.query
		if (query.redirect) {
			try {
				redirect.value = query.redirect as string
				otherQuery.value = getOtherQuery(query)
			} catch (error) {
				redirect.value = null
			}
		}
	},
	{ immediate: true }
)

const formModel = ref({
	userName: '',
	password: '',
	rememberMe: false,
	code: '',
	uuid: ''
})
const formRule = ref({
	userName: [
		{
			required: true,
			message: '请输入您的账号',
			trigger: 'blur'
		}
	],
	password: [
		{
			required: true,
			message: '请输入您的密码',
			trigger: 'blur'
		}
	],
	code: [
		{
			required: true,
			message: '请输入验证码',
			trigger: 'blur'
		}
	]
})
const formRef = ref<null | FormInstance>(null)
const userStore = useUserStore()
async function submit() {
	await formRef.value?.validate()
	try {
		loading.value = true
		const [err] = await to(
			userStore.login({
				userName: formModel.value.userName,
				password: formModel.value.password,
				code: formModel.value.code,
				uuid: formModel.value.uuid
			})
		)
		if (err) {
			getCaptchaImage()
			loading.value = false
			return
		}

		// 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
		if (formModel.value.rememberMe) {
			Cookies.set('userName', formModel.value.userName, { expires: 30 })
			Cookies.set('password', encrypt(formModel.value.password), { expires: 30 })
			Cookies.set('rememberMe', formModel.value.rememberMe.toString(), { expires: 30 })
		} else {
			// 否则移除
			Cookies.remove('userName')
			Cookies.remove('password')
			Cookies.remove('rememberMe')
		}

		router.push({
			path: redirect.value || '/',
			query: otherQuery.value
		})
	} finally {
		loading.value = false
	}
}

const immediateDebounce: any = debounce(() => submit(), 800, {
	edges: ['leading']
})

useEventListener(document, 'keydown', ({ code }) => {
	if (['Enter', 'NumpadEnter'].includes(code) && !loading.value) {
		immediateDebounce()
	}
})

const codeImg = ref('')
async function getCaptchaImage() {
	const result = await captchaImage()
	codeImg.value = 'data:image/gif;base64,' + result.data.img
	formModel.value.uuid = result.data.uuid
}
function getCookie() {
	const userName = Cookies.get('userName')
	const password = Cookies.get('password')
	const rememberMe = Cookies.get('rememberMe')
	formModel.value.userName = userName === undefined ? formModel.value.userName : userName

	formModel.value.password = password === undefined ? formModel.value.password : decrypt(password)

	formModel.value.rememberMe = rememberMe === undefined ? false : Boolean(rememberMe)
}
getCaptchaImage()
getCookie()
</script>

<template>
	<div class="h-screen w-screen bg-#2d3a4b overflow-auto select-none flex items-center justify-center">
		<div class="bg-white rounded-2 p-6 w-100">
			<div class="text-#707070 text-4.5 text-center mb-7.5 test-class">{{ appTitle }}</div>
			<ElForm
				ref="formRef"
				:model="formModel"
				:rules="formRule"
				class="form"
			>
				<ElFormItem
					prop="userName"
					label=""
				>
					<ElInput
						v-model.trim="formModel.userName"
						type="text"
						clearable
						:prefix-icon="User"
						placeholder="账号"
						class="h-9.5"
						autocomplete="off"
					/>
				</ElFormItem>
				<ElFormItem
					prop="password"
					label=""
				>
					<ElInput
						ref="passwordRef"
						v-model.trim="formModel.password"
						type="password"
						clearable
						:prefix-icon="Lock"
						placeholder="密码"
						autocomplete="off"
						class="h-9.5"
					/>
				</ElFormItem>

				<ElFormItem prop="code">
					<div class="flex justify-between">
						<div class="w-63%">
							<ElInput
								v-model="formModel.code"
								auto-complete="off"
								placeholder="验证码"
								class="h-9.5 w-100%"
							>
								<template #prefix>
									<svg-icon
										icon-class="validCode"
										size="14"
									/>
								</template>
							</ElInput>
						</div>
						<img
							:src="codeImg"
							class="h-9.5 cursor-pointer"
							@click="getCaptchaImage"
						/>
					</div>
				</ElFormItem>

				<ElFormItem>
					<ElCheckbox v-model="formModel.rememberMe">记住密码</ElCheckbox>
				</ElFormItem>
				<ElButton
					type="primary"
					class="w-full"
					size="large"
					:loading="loading"
					@click="submit"
				>
					登录
				</ElButton>
			</ElForm>
		</div>
	</div>
</template>
